/*
 * Licensed to the 南京汇海交通科技有限公司
 *
 * Copyright (c) 2025.
 * All rights reserved.
 *
 * 本软件属南京汇海交通科技有限公司所有，在未获得南京汇海交通科技有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.chframework.boot.core.response.result;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.chframework.common.context.SpringContextHolder;
import com.chframework.common.exception.ApplicationException;
import com.chframework.common.extend.HttpsHelper;
import com.chframework.common.web.IApiResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull;

import java.io.Serializable;

/**
 * open-api 响应结果。
 * <p>
 * 1、应用部署后的网络访问方式 采用HTTPS安全传输协议。
 * <p>
 * 2、为了提升应用的吞吐量，决定采用Spring-WebFlux技术 搭建开发框架。
 * <p>
 * 3、返回该对象之前，需要从请求头拿到app-key，再去数据库拿到secret-key。
 * <p>
 * 4、使用secret-key将json报文加密，最后返回给web-service，再走网络传输给外部。
 */
@Slf4j
public final class HttpsResult implements Serializable {

    private static final ObjectMapper OBJECT_MAPPER;
    private String encrypt;

    private HttpsResult() {
    }

    static {
        OBJECT_MAPPER = SpringContextHolder.getBean(ObjectMapper.class);
    }

    /**
     * 构建open api的在外网的响应对象
     */
    @NonNull
    public static HttpsResult createResult(@NonNull IApiResult<?> apiResult) throws ApplicationException {
        try {
            String apiResultJson = OBJECT_MAPPER.writeValueAsString(apiResult);

            HttpsResult result = new HttpsResult();
            result.setEncrypt(apiResultJson);

            return result;
        } catch (Exception e) {
            throw new ApplicationException(e);
        }
    }

    /**
     * 将原始数据加密
     */
    public HttpsResult encrypt(@NonNull String secretKey) throws ApplicationException {
        try {
            String apiResultJson = this.getEncrypt();

            String encryptContent = HttpsHelper.encrypt(apiResultJson, secretKey);
            this.setEncrypt(encryptContent);

            return this;
        } catch (Exception e) {
            throw new ApplicationException(e);
        }
    }

    /**
     * 获取原始数据
     */
    public HttpsResult decrypt(@NonNull String secretKey) throws ApplicationException {
        try {
            String apiResultJson = this.getEncrypt();
            this.setEncrypt(HttpsHelper.decrypt(apiResultJson, secretKey));

            return this;
        } catch (Exception e) {
            throw new ApplicationException(e);
        }
    }

    /**
     * 获取加密后的网络消息报文
     */
    @NonNull
    public String getEncrypt() {
        return StringUtils.isEmpty(encrypt) ? StringUtils.EMPTY : encrypt;
    }

    /**
     * 设置加密后的网络消息报文
     */
    public void setEncrypt(@NonNull String encrypt) {
        this.encrypt = encrypt;
    }

}
